/*
+--------------------------------------------------------------------------
|   Mblog [#RELEASE_VERSION#]
|   ========================================
|   Copyright (c) 2014, 2015 mtons. All Rights Reserved
|   http://www.mtons.com
|
+---------------------------------------------------------------------------
*/
package com.mtons.mblog.web.controller.admin;

import static cn.hutool.core.date.DatePattern.NORM_DATETIME_MINUTE_FORMATTER;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mtons.mblog.base.lang.Result;
import com.mtons.mblog.base.utils.BlogUtils;
import com.mtons.mblog.base.utils.HttpUtils;
import com.mtons.mblog.config.ContextStartup;
import com.mtons.mblog.modules.data.DingTalkMd;
import com.mtons.mblog.modules.data.DingTalkMsg;
import com.mtons.mblog.modules.data.DingTalkResponse;
import com.mtons.mblog.modules.job.LearnJob;
import com.mtons.mblog.modules.service.OptionsService;
import com.mtons.mblog.modules.service.PostSearchService;
import com.mtons.mblog.web.controller.BaseController;
import java.util.Date;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;

/**
 * 系统配置
 *
 * @author langhsu
 *
 */
@Slf4j
@Controller
@RequestMapping("/admin/options")
public class OptionsController extends BaseController {
	@Autowired
	private OptionsService optionsService;
	@Autowired
	private PostSearchService postSearchService;
	@Autowired
	private ContextStartup contextStartup;

	public static int startFlag = 0;

	public static int lastVal = 0;

	public static int maxShowCount = 6;

	public static int bigCount = 0;

	public static int bigCountLimit = 2;

	public static Map<Integer,Integer> showMap = initShowMap();

	public static final long TEN_M = 1000*60*10;

	public static final long TWO_M = 1000*60*2;

	public static boolean show = true;

	private static String cookieTemp;

	@RequestMapping("/index")
	public String index(ModelMap model) {
		return "/admin/options/index";
	}

	@RequestMapping(value = "/start",produces = "application/json; charset=utf-8")
	@ResponseBody
	public Result start(){
		lastVal = 0;
		show = siteOptions.getShow();
		if(startFlag == 0) {
			startFlag = 1;
			ThreadUtil.execute(() -> gps());
			sendDingTalk("电量监测", "开启电量监测,当前："+(show?"展示电量":"不展示电量")+"，同时断电告警");
		}else {
			sendDingTalk("电量监测", "已经开启电量监测，请不要频繁开启");
		}
		return Result.success("start");
	}

	@RequestMapping(value = "/start2",produces = "application/json; charset=utf-8")
	@ResponseBody
	public Result start2(){
		lastVal = 0;
		show = true;
		if(startFlag == 0) {
			startFlag = 1;
			ThreadUtil.execute(() -> gps());
			sendDingTalk("电量监测", "开启电量监测,当前："+(show?"展示电量":"不展示电量")+"，同时断电告警");
		}else {
			sendDingTalk("电量监测", "已经开启电量监测，请不要频繁开启");
		}
		return Result.success("start-show");
	}

	@RequestMapping(value = "/stop",produces = "application/json; charset=utf-8")
	@ResponseBody
	public Result stop(){
		stopAlarm();
		sendDingTalk("电量监测", "关闭电量监测");
		return Result.success("stop");
	}

	public void gps() {
		long sleepTime = TEN_M;
		while(startFlag == 1) {
			String resultJson = null;
			try {
				// 登录页面地址
				String loginPageUrl = "http://www.yugps.com/Account/Login?ReturnUrl=%2F";
				// 登录请求参数
				String loginUrl = "http://www.yugps.com/Account/Login";
				String loginJson = "{\"userName\":\"18911222574\",\"password\":\"222204\",\"loginType\":\"UserNameAndPassword\"}";

				// 获取数据请求参数
				String dataUrl = "http://www.yugps.com/Position/GetMonitorData";
				String dataJson = "{\"skipCount\":0,\"maxResultCount\":10,\"searchText\":\"\",\"searchType\":\"all\",\"deviceGroupId\":\"\",\"coordinates\":\"Gcj02\"}";

				if (StrUtil.isEmpty(cookieTemp)) {
					// 发送GET请求获取Cookie
					HttpResponse loginPageResponse = HttpRequest.get(loginPageUrl).execute();
					String cookie = loginPageResponse.getCookieStr();
					// 使用Cookie发送登录请求
					HttpResponse loginResponse = HttpRequest.post(loginUrl)
							.header("Cookie", cookie)
							.body(loginJson)
							.execute();
					cookieTemp = cookie;
					String loginResult = loginResponse.body();
					if (loginResponse.getStatus() != 200) {
						log.info("Login failed!");
						sendDingTalk("电量监测", "开启电量监测发现系统可能无法访问");
						cookieTemp = null;
						return;
					}
					log.info("此次进行登陆");
					//预防服务端没反应过来，等待5秒再访问
					Thread.sleep(5000);
				}
				// 判断登录是否成功，这里简单通过状态码判断，具体根据实际情况进行修改
				// 使用Cookie发送请求获取数据
				HttpResponse dataResponse = HttpRequest.post(dataUrl)
						.header("Cookie", cookieTemp)
						.body(dataJson)
						.execute();
				resultJson = dataResponse.body();
				// 解析结果并提取所需数据
				cn.hutool.json.JSONObject resultObj = JSONUtil.parseObj(resultJson);
				cn.hutool.json.JSONArray itemsArray = resultObj.getJSONObject("result")
						.getJSONArray("items");
				cn.hutool.json.JSONObject itemObj = itemsArray.getJSONObject(0);
				String winDeviceStatusText = itemObj.getStr("winDeviceStatusText");
				//已设防 电量76% 电压67.5V 信号21
				if (StrUtil.isNotEmpty(winDeviceStatusText)) {
					String resultArr = StrUtil.subBetween(winDeviceStatusText,"电量","%");
					if (StrUtil.isNotEmpty(resultArr)) {
						int numberStatus = Integer.parseInt(resultArr);
						int level = numberStatus / 10;
						Integer count = showMap.get(level);
						if (count < maxShowCount && level != 10 && show) {
							sendDingTalk("正在充电,电量"+numberStatus,
									"正在充电，当前电量为：" + numberStatus + "，发生时间：" + DateUtil.format(new Date(),
											NORM_DATETIME_MINUTE_FORMATTER));
							showMap.put(level, ++count);
						}
						if (numberStatus <= lastVal) {
							boolean flag = false;
							for (int i = 92; i <= 99; i++) {
								if (numberStatus == i && ++bigCount < bigCountLimit) {
									flag = true;
									break;
								} else {
									bigCount = 0;
								}
							}
							if(flag){
								continue;
							}
							String msg = "，一直未变化，有可能已经断电了，";
							if(numberStatus < lastVal){
								msg = "，相比上一次减少了，将两分钟监测一次，请留意以防恶意断电！";
								sleepTime = TWO_M;
							}
							sendDingTalk("断电警告，电量"+numberStatus,
									"当前电量为" + numberStatus + msg + "发生时间：" + DateUtil.format(
											new Date(), NORM_DATETIME_MINUTE_FORMATTER));
						} else {
								lastVal = numberStatus;
								sleepTime = TEN_M;
						}
						if (numberStatus >= 100) {
							sendDingTalk("已经充满,电量:"+numberStatus,
									"当前已经充满电了,可能还需要再充30分钟以上才能实际充满，发生时间：" + DateUtil.format(new Date(),
											NORM_DATETIME_MINUTE_FORMATTER));
							stopAlarm();
						}
						log.info("电量：" + numberStatus);
					} else {
						log.info("解析异常");
					}
				}
				// 输出所需数据
				log.info("winDeviceStatusText: " + winDeviceStatusText);
			} catch (Exception ex) {
				log.error("定位出错", ex);
				log.error("出错的json->"+resultJson);
				sendDingTalk("监测出错", ex.getMessage());
				cookieTemp = null;
			}finally {
				ThreadUtil.safeSleep(sleepTime);
			}
		}
	}

	private void stopAlarm() {
		startFlag = 0;
		lastVal = 0;
		showMap = initShowMap();
	}

	private static HashMap<Integer, Integer> initShowMap() {
		return new HashMap<Integer, Integer>() {
			{
				put(0, 0);
				put(1, 0);
				put(2, 0);
				put(3, 0);
				put(4, 0);
				put(5, 0);
				put(6, 0);
				put(7, 0);
				put(8, 0);
				put(9, 0);
				put(10, 0);
			}
		};
	}

	public void sendDingTalk(String title, String content) {
		DingTalkMsg dingTalkMsg = new DingTalkMsg();
		dingTalkMsg.setMsgtype("markdown");
		DingTalkMd markdown = new DingTalkMd();
		markdown.setTitle(title);
		markdown.setText(content);
		dingTalkMsg.setMarkdown(markdown);
		String dingTalkStr = JSONObject.toJSONString(dingTalkMsg);
		try {
			String post = HttpUtils.postObj(
					"https://oapi.dingtalk.com/robot/send?access_token=e4312cdbf6795bcc0f104c91e6a612154100e29a27521f2cace4f8872ee900b7",
					dingTalkStr);
			DingTalkResponse dingTalkResponse = JSON.parseObject(post, DingTalkResponse.class);
			if (dingTalkResponse != null && dingTalkResponse.getErrcode() == 310000) {
				log.warn("调用钉钉返回错误，信息为{}", post);
			}
		} catch (Exception e) {
			log.error("调用钉钉有问题:" + title, e);
		}
	}


	@RequestMapping("/update")
	public String update(@RequestParam Map<String, String> body, ModelMap model) {
		optionsService.update(body);
		contextStartup.reloadOptions(false);
		model.put("data", Result.success());
		return "/admin/options/index";
	}

	/**
	 * 刷新系统变量
	 * @return
	 */
	@RequestMapping("/reload_options")
	@ResponseBody
	public Result reloadOptions() {
		contextStartup.reloadOptions(false);
		contextStartup.resetChannels();
		return Result.success();
	}

	@RequestMapping("/reset_indexes")
	@ResponseBody
	public Result resetIndexes() {
		postSearchService.resetIndexes();
		return Result.success();
	}
}
